#include "src/net/http/http_request.h"

namespace fio66::net {

void HttpRequest::SetVersion(HttpVersion v) { version_ = v; }

HttpVersion HttpRequest::Version() const { return version_; }

std::string_view HttpRequest::VersionString() const{
  switch(version_) {
    case HttpVersion::kHttp10:
      return "HTTP 1.0";
    case HttpVersion::kHttp11:
      return "HTTP 1.1";
    default:
      return "unknow";
  }
}

bool HttpRequest::SetMethod(std::string_view method) {
  // 浏览器同一个HttpConnection会给两个Http请求
  //assert(method_ == HttpMethod::kInvalid);
  if (method == "GET") {
    method_ = HttpMethod::kGet;
  } else if (method == "POST") {
    method_ = HttpMethod::kPost;
  } else if (method == "HEAD") {
    method_ = HttpMethod::kHead;
  } else if (method == "PUT") {
    method_ = HttpMethod::kPut;
  } else if (method == "DELETE") {
    method_ = HttpMethod::kDelete;
  } else {
    method_ = HttpMethod::kInvalid;
  }
  return HttpMethod::kInvalid != method_;
}

HttpMethod HttpRequest::Method() const { return method_; }

std::string_view HttpRequest::MethodString() const {
  switch (method_) {
    case HttpMethod::kGet:
      return "GET";
    case HttpMethod::kPost:
      return "POST";
    case HttpMethod::kHead:
      return "HEAD";
    case HttpMethod::kPut:
      return "PUT";
    case HttpMethod::kDelete:
      return "DELETE";
    default:
      return "UNKNOW";
  }
}

void HttpRequest::SetPath(std::string_view path) { path_ = path; }

std::string_view HttpRequest::Path() const { return path_; }

void HttpRequest::SetQuery(std::string_view query) { query_ = query; }

std::string_view HttpRequest::Query() const { return query_; }

void HttpRequest::SetReceiveTime(Timestamp t) { receive_time_ = t; }

Timestamp HttpRequest::ReceiveTime() const { return receive_time_; }

void HttpRequest::AddHeader(const char* start, const char* colon,
                            const char* end) {
  std::string field(start, colon);
  colon++;
  while (colon < end && isspace(*colon)) {
    colon++;
  }

  std::string value(colon, end);
  while (!value.empty() && isspace(value[value.size() - 1])) {
    value.pop_back();
  }
  headers_[std::move(field)] = std::move(value);
}

std::string_view HttpRequest::GetHeader(const std::string& field) const {
  const auto it = headers_.find(field);
  if (it != headers_.cend()) {
    return it->second;
  }
  return "";
}

const std::map<std::string, std::string> HttpRequest::Headers() const {
  return headers_;
}

void HttpRequest::Swap(HttpRequest& that) {
  std::swap(method_, that.method_);
  std::swap(version_, that.version_);
  path_.swap(that.path_);
  query_.swap(that.query_);
  receive_time_.Swap(that.receive_time_);
  headers_.swap(that.headers_);
}

}  // namespace fio66::net
